#ifndef __M_FILE_H__
#define __M_FILE_H__

#include <psp2common/types.h>

#define SCE_ERROR_ERRNO_EEXIST 0x80010011
#define SCE_ERROR_ERRNO_ENODEV 0x80010013

#define MAX_PATH_LENGTH 1024
#define MAX_NAME_LENGTH 256
#define MAX_SHORT_NAME_LENGTH 64

#define DIRECTORY_SIZE (4 * 1024)
#define TRANSFER_SIZE (128 * 1024)

enum FileTypes
{
    FILE_TYPE_UNKNOWN,
    FILE_TYPE_ARCHIVE,
    FILE_TYPE_BMP,
    FILE_TYPE_INI,
    FILE_TYPE_JPEG,
    FILE_TYPE_MP3,
    FILE_TYPE_MP4,
    FILE_TYPE_OGG,
    FILE_TYPE_PNG,
    FILE_TYPE_PSP2DMP,
    FILE_TYPE_SFO,
    FILE_TYPE_TXT,
    FILE_TYPE_VPK,
    FILE_TYPE_XML,
};

enum FileSortFlags
{
    SORT_NONE,
    SORT_BY_NAME,
    SORT_BY_SIZE,
    SORT_BY_DATE,
};

enum FileMoveFlags
{
    MOVE_INTEGRATE = 0x1, // Integrate directories
    MOVE_REPLACE = 0x2,   // Replace files
};

typedef struct
{
    uint64_t *value;
    uint64_t max;
    void (*SetProgress)(uint64_t value, uint64_t max);
    int (*cancelHandler)();
} FileProcessParam;

typedef struct FileListEntry
{
    struct FileListEntry *next;
    struct FileListEntry *previous;
    char *name;
    int name_length;
    char *info;
    int is_folder;
    int type;
    int is_selected;
    SceOff size;
    SceOff size2;
    SceDateTime ctime;
    SceDateTime mtime;
    SceDateTime atime;
} FileListEntry;

typedef struct
{
    FileListEntry *head;
    FileListEntry *tail;
    int length;
    char path[MAX_PATH_LENGTH];
    int files;
    int folders;
    int selected_num;
} FileList;

int ReadFile(const char *file, void *buf, int size);
int WriteFile(const char *file, const void *buf, int size);
int allocateReadFile(const char *file, void **buffer);

int checkFileExist(const char *file);
int checkFolderExist(const char *folder);

int createFolder(const char *path);

char *getBaseDirectory(const char *path);
char *getFilename(const char *path);
char *getBaseName(const char *path);

int makeBaseDirectory(char *dst_path, const char *src_path, int size);
int makeFilename(char *dst_name, const char *src_path, int size);
int makeBaseName(char *dst_name, const char *src_path, int size);

int getFileSize(const char *file);
int removePath(const char *path, FileProcessParam *param);
int copyFile(const char *src_path, const char *dst_path, FileProcessParam *param);
int copyPath(const char *src_path, const char *dst_path, FileProcessParam *param);
int movePath(const char *src_path, const char *dst_path, int flags, FileProcessParam *param);

int getNumberOfDevices();
char **getDevices();

FileListEntry *fileListCopyEntry(FileListEntry *src);
FileListEntry *fileListGetEntryByName(FileList *list, const char *name);
FileListEntry *fileListGetEntryByNumber(FileList *list, int n);
int fileListGetNumberByName(FileList *list, const char *name);

void fileListAddEntry(FileList *list, FileListEntry *entry, int sort);
int fileListRemoveEntry(FileList *list, FileListEntry *entry);
int fileListRemoveEntryByName(FileList *list, const char *name);

void fileListSelectAll(FileList *list);
void fileListUnselectAll(FileList *list);

void fileListEmpty(FileList *list);

int fileListGetEntries(FileList *list, const char *path, int sort);

int writePngFile(const char *path, unsigned char *pixels, int width, int height, int bit_depth);

#endif
